package com.haiyou.common.util.string;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

public class StringUtil {
	private static final String NUMBER = "0123456789";
	private static final String ENGLISH_CHARS_LOWER = "abcdefghijklmnopqrstuvwxyz";

	/**
	 * 生产一个指定长度的随机字符串
	 * @param length 字符串长度
	 * @return
	 */
	public static String generateRandomString(int length) {
		StringBuilder sb = new StringBuilder(length);
		SecureRandom random = new SecureRandom();
		for (int i = 0; i < length; i++) {
			if(i < 2){
				sb.append(ENGLISH_CHARS_LOWER.charAt(random.nextInt(ENGLISH_CHARS_LOWER.length())));
			}else if(i < 8){
				sb.append(NUMBER.charAt(random.nextInt(NUMBER.length())));
			}else{
				sb.append(ENGLISH_CHARS_LOWER.charAt(random.nextInt(ENGLISH_CHARS_LOWER.length())));
			}
		}
		return sb.toString();
	}
	
	/**
	 * 首字母大写
	 */
	public static String upperCaseFirst(String str){
		char chs[] = str.toCharArray();
		chs[0] = Character.toUpperCase(chs[0]);
		return new String(chs);
	}
	
	/**
	 * 获得激活码（8位）
	 */
	public static String randomString(int length){
		String uuid = UUID.randomUUID().toString();
		uuid = uuid.replace("-", "");
		return uuid.substring(0, length);
	}
	
	/**
	 * 名称是否合法
	 */
	public static boolean checkUserName(String userName) {
		String regex = "([a-z]|[A-Z]|[0-9]|[\\u4e00-\\u9fa5])+";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(userName);
		return m.matches();
	}

	/**
	 * 是否数字
	 */
	public static boolean isNumeric(String str){ 
		if(str == null || str.length() <= 0){
			return false;
		}
		Pattern pattern = Pattern.compile("[0-9]*"); 
		Matcher isNum = pattern.matcher(str);
		if( !isNum.matches() ){
			return false; 
		} 
		return true; 
	}
	
	/**
	 * 获取名字长度
	 * @param name
	 * @return
	 */
	public static int getLenght(String name){
		int count = 0;
		for(char c : name.toCharArray()){
			//if((c >= '0' && c<='9') || (c >= 'a' && c<='z') || (c>='A' && c<='Z') || isEnPunc(c) ){
			if(c < 128){	//跟客户端同步
				count ++;
			}else{
				count += 2;
			}
		}
		return count;
	}

	public static boolean isEnPunc(char ch) {
		if (0x21 <= ch && ch <= 0x22)
			return true;
		if (ch == 0x27 || ch == 0x2C)
			return true;
		if (ch == 0x2E || ch == 0x3A)
			return true;
		if (ch == 0x3B || ch == 0x3F)
			return true;
		return false;
	}

	public static boolean isCjkPunc(char ch) {
		if (0x3001 <= ch && ch <= 0x3003)
			return true;
		if (0x301D <= ch && ch <= 0x301F)
			return true;
		return false;
	}

	/**
	 * 解析byte数组 
	 */
	public static byte[] parseArrayByByte(String str, String split){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new byte[0];
		}
		String strs[] = str.split(split);
		byte[] values = new byte[strs.length];
		for(int i = 0; i < strs.length; i++){
			values[i] = Byte.parseByte(strs[i].trim());
		}
		return values;
	}
	
	/**
	 * 解析float数组 
	 */
	public static float[] parseArrayByFloat(String str, String split){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new float[0];
		}
		String strs[] = str.split(split);
		float[] values = new float[strs.length];
		for(int i = 0; i < strs.length; i++){
			values[i] = Float.parseFloat(strs[i].trim());
		}
		return values;
	}

	/**
	 * 解析int数组 
	 */
	public static int[] parseArrayByInt(String str, String split){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new int[0];
		}
		String strs[] = str.split(split);
		int[] values = new int[strs.length];
		for(int i = 0; i < strs.length; i++){
			values[i] = Integer.parseInt(strs[i].trim());
		}
		return values;
	}
	
	public static int[] parseArrayByInt(String str, String split1, String split2){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new int[0];
		}
		String[] strs = str.split(split1);
		String[] subs = strs[0].split(split2);
		int sl = subs.length;
		int[] values = new int[strs.length * sl];
		for(int i = 0; i < strs.length; i++){
			subs = strs[i].trim().split(split2);
			for(int j = 0; j < sl; j++){
				values[i * sl + j] = Integer.parseInt(subs[j].trim());
			}
		}
		return values;
	}
	
	/**
	 * 解析long数组 
	 */
	public static long[] parseArrayByLong(String str, String split){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new long[0];
		}
		String strs[] = str.split(split);
		long[] values = new long[strs.length];
		for(int i = 0; i < strs.length; i++){
			values[i] = Long.parseLong(strs[i].trim());
		}
		return values;
	}
	
	public static String[] parseArray(String str, String split){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new String[0];
		}
		return str.split(split);
	}
	
	/**
	 * 数组转string
	 */
	public static <T> String formatArray(T[] array, String format){
		if(array == null || array.length <= 0){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for(int i = 0; i < array.length; i++){
			if(i != 0){
				buffer.append(format);
			}
			buffer.append(array[i]);
		}
		return buffer.toString();
	}
	
	/**
	 * 数组转string
	 */
	public static String formatArray(int[] array, String format){
		if(array == null || array.length <= 0){
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		for(int i = 0; i < array.length; i++){
			if(i != 0){
				buffer.append(format);
			}
			buffer.append(array[i]);
		}
		return buffer.toString();
	}
	
	/**
	 * 可变参转string
	 */
	public static String format(String format, Object... objects){
		if(objects == null || objects.length == 0){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for(Object obj : objects){
			if(buffer.length() > 0){
				buffer.append(format);
			}
			buffer.append(obj);
		}
		return buffer.toString();
	}

	/**
	 * 可变参转string
	 */
	public static void append(StringBuffer buffer, String format, Object... objects){
		if(objects == null || objects.length == 0){
			return;
		}
		for(int i = 0; i < objects.length; i++){
			Object obj = objects[i];
			if(i > 0){
				buffer.append(format);
			}
			buffer.append(obj);
		}
	}
	
	/**
	 * 数组转string
	 */
	public static String formatArray(short array[], String format){
		if(array == null || array.length <= 0){
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		for(int i = 0; i < array.length; i++){
			if(i != 0){
				buffer.append(format);
			}
			buffer.append(array[i]);
		}
		return buffer.toString();
	}
	
	/**
	 * 数组转string
	 */
	public static String formatArray(long array[], String format){
		if(array == null || array.length <= 0){
			return null;
		}
		StringBuffer buffer = new StringBuffer();
		for(int i = 0; i < array.length; i++){
			if(i != 0){
				buffer.append(format);
			}
			buffer.append(array[i]);
		}
		return buffer.toString();
	}
	
	/**
	 * 解析int列表
	 */
	public static List<Integer> parseListByInt(String str, String split){
		List<Integer> list = new ArrayList<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Integer.valueOf(val.trim()));
		}
		return list;
	}
	
	/**
	 * 解析int列表
	 */
	public static List<Integer> parseListByInt2(String str, String split){
		List<Integer> list = new ArrayList<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			if("".equals(val.trim()) || val.trim().length() == 0){
				continue;
			}
			list.add(Integer.valueOf(val.trim()));
		}
		return list;
	}
	
	
	/**
	 * 解析byte列表
	 */
	public static List<Byte> parseListByByte(String str, String split){
		List<Byte> list = new ArrayList<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Byte.valueOf(val.trim()));
		}
		return list;
	}

	/**
	 * 解析long列表
	 */
	public static List<Long> parseListByLong(String str, String split){
		List<Long> list = new ArrayList<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Long.valueOf(val.trim()));
		}
		return list;
	}

	/**
	 * 解析String列表
	 */
	public static List<String> parseListByString(String str, String split){
		List<String> list = new ArrayList<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(val.trim());
		}
		return list;
	}
	
	public static int[][] parseTwoArrayByInt(String str, String split1, String split2){
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return new int[0][0];
		}
		String strs[] = str.split(split1);
		int length = strs.length;
		int[][] values = new int[length][length];
		try{
			for(int i = 0; i < length; i++){
				String st = strs[i].trim();
				String[] vals = st.split(split2);
				if(vals.length != length){
					throw new Exception("split two array exception! length error " + length + "-" + i + "-" + vals.length);
				}
				for(int j = 0; j < length; j++){
					values[i][j] = Integer.valueOf(vals[j]);
				}
			}
		}catch(Throwable e){
			e.printStackTrace();
			return null;
		}
		return values;
	}
	
	/**
	 * list转string
	 */
	public static String formatList(List<?> list, String format){
		if(list == null || list.isEmpty()){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for(int i = 0; i < list.size(); i++){
			if(i != 0){
				buffer.append(format);
			}
			buffer.append(list.get(i));
		}
		return buffer.toString();
	}
	
	/**
	 * list转string
	 */
	public static String formatSet(Set<?> list, String format){
		if(list == null || list.isEmpty()){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		int index = 0;
		for (Object i : list) {
			if(index != 0){
				buffer.append(format);
			}
			buffer.append(i);
			index ++;
		}
		return buffer.toString();
	}
	
	
	/**
	 * 解析int列表
	 */
	public static Set<Integer> parseSetByInt(String str, String split){
		Set<Integer> list = new HashSet<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Integer.valueOf(val.trim()));
		}
		return list;
	}
	
	/**
	 * 解析int列表
	 */
	public static Set<Integer> parseTreeSetByInt(String str, String split){
		Set<Integer> list = new TreeSet<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Integer.valueOf(val.trim()));
		}
		return list;
	}
	
	/**
	 * 解析Byte列表
	 */
	public static Set<Byte> parseSetByByte(String str, String split){
		Set<Byte> list = new HashSet<>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return list;
		}
		String strs[] = str.split(split);
		for(String val : strs){
			list.add(Byte.valueOf(val.trim()));
		}
		return list;
	}
	
	/**
	 * 解析map <Byte, Short>
	 */
	public static Map<Byte, Short> parseMapByByteShort(String str, String split1, String split2){
		Map<Byte, Short> map = new HashMap<Byte, Short>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Byte.valueOf(data[0].trim()), Short.valueOf(data[1].trim()));
		}
		return map;
	}

	/**
	 * 解析map <Short, Integer>
	 */
	public static Map<Short, Integer> parseMapByShortInt(String str, String split1, String split2){
		Map<Short, Integer> map = new HashMap<Short, Integer>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Short.valueOf(data[0].trim()), Integer.valueOf(data[1].trim()));
		}
		return map;
	}
	/**
	 * 解析map <Byte, Integer>
	 */
	public static Map<Byte, Integer> parseMapByByteInt(String str, String split1, String split2){
		Map<Byte, Integer> map = new HashMap<Byte, Integer>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Byte.valueOf(data[0].trim()), Integer.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Byte, Double>
	 */
	public static Map<Byte, Double> parseMapByByteDouble(String str, String split1, String split2){
		Map<Byte, Double> map = new HashMap<Byte, Double>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Byte.valueOf(data[0].trim()), Double.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, Byte>
	 */
	public static Map<Integer, Byte> parseMapByIntByte(String str, String split1, String split2){
		Map<Integer, Byte> map = new HashMap<Integer, Byte>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Integer.valueOf(data[0].trim()), Byte.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, Short>
	 */
	public static Map<Integer, Short> parseMapByIntShort(String str, String split1, String split2){
		Map<Integer, Short> map = new HashMap<Integer, Short>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Integer.valueOf(data[0].trim()), Short.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, Long>
	 */
	public static Map<Integer, Long> parseMapByIntLong(String str, String split1, String split2){
		Map<Integer, Long> map = new HashMap<Integer, Long>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Integer.valueOf(data[0].trim()), Long.valueOf(data[1].trim()));
		}
		return map;
	}

	/**
	 * 解析map <Byte, Byte>
	 */
	public static Map<Byte, Byte> parseMapByByte(String str, String split1, String split2){
		Map<Byte, Byte> map = new HashMap<Byte, Byte>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Byte.valueOf(data[0].trim()), Byte.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, Integer>
	 */
	public static Map<Integer, Integer> parseMapByInt(String str, String split1, String split2){
		Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Integer.valueOf(data[0].trim()), Integer.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, String>
	 */
	public static Map<Integer, String> parseMapByIntStr(String str, String split1, String split2){
		Map<Integer, String> map = new HashMap<Integer, String>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(Integer.valueOf(data[0].trim()), data[1].trim());
		}
		return map;
	}
	
	/**
	 * 解析map <String, Integer>
	 */
	public static Map<String, Integer> parseMapByStrInt(String str, String split1, String split2){
		Map<String, Integer> map = new HashMap<String, Integer>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length != 2){
				continue;
			}
			map.put(data[0].trim(), Integer.valueOf(data[1].trim()));
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, int[]>
	 */
	public static Map<Integer, int[]> parseMapByIntArray(String str, String split1, String split2){
		Map<Integer, int[]> map = new HashMap<Integer, int[]>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return map;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length < 2){
				continue;
			}
			int[] vals = new int[data.length - 1];
			for(int i = 1; i < vals.length; i++){
				vals[i - 1] = Integer.valueOf(data[i].trim());
			}
			map.put(Integer.valueOf(data[0].trim()), vals);
		}
		return map;
	}
	
	/**
	 * 解析map <Integer, Map<Integer,Integer>>
	 */
	public static Map<Integer, Map<Integer,Integer>> parseMapsByIntArray(String str, String split1, String split2){
		Map<Integer, Map<Integer,Integer>> maps = new HashMap<Integer, Map<Integer,Integer>>();
		if(str == null || str.length() == 0 
				|| (str = str.trim()).length() == 0){
			return maps;
		}
		String[] strs = str.split(split1);
		for(String st : strs){
			String[] data = st.trim().split(split2);
			if(data.length < 2){
				continue;
			}
			Map<Integer,Integer> map = maps.get(Integer.valueOf(data[0].trim()));
			if(map==null){
				map = new HashMap<>();
			}
			map.put(Integer.valueOf(data[1].trim()), Integer.valueOf(data[2].trim()));
			maps.put(Integer.valueOf(data[0].trim()), map);
		}
		return maps;
	}
	
	/**
	 * <Integer, Map<Integer,Integer>> 转 string
	 */
	public static String parseStringByIntArray(Map<Integer, Map<Integer,Integer>> maps, String format1, String format2){
		if(maps == null || maps.isEmpty()){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for (Integer key : maps.keySet()) {
			if(buffer.length() > 0){
				buffer.append(format1);
			}
			Map<Integer,Integer> map = maps.get(key);
			if(map!=null){
				for(Entry<Integer, Integer> keyValue : map.entrySet()){
					buffer.append(key).append(format2);
					buffer.append(keyValue.getKey()).append(format2);
					buffer.append(keyValue.getValue());
					buffer.append(format1);
				}
			}
			
		}
		return buffer.toString();
	}
	
	
	/**
	 * map转string
	 */
	public static String formatMap(Map<?, ?> map, String format1, String format2){
		if(map == null || map.isEmpty()){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		for (Object key : map.keySet()) {
			if(buffer.length() > 0){
				buffer.append(format1);
			}
			buffer.append(key).append(format2);
			Object obj = map.get(key);
			if(obj.getClass().isArray()){
				Object[] objs = (Object[]) obj;
				for(int i = 0; i < objs.length; i++){
					if(i != 0){
						buffer.append(format2);
					}
					buffer.append(objs[i]);
				}
			}else{
				buffer.append(obj);
			}
		}
		return buffer.toString();
	}
	
	public static String toString(Object bean){
		if(bean == null){
			return "";
		}
		StringBuffer buffer = new StringBuffer();
		Class<?> clazz = bean.getClass();
		try{
			while(clazz != Object.class){
				Field[] fields = clazz.getDeclaredFields();
				for(Field field : fields){
					if(field.getName().equals("serialVersionUID")){
						continue;
					}
					if(buffer.length() != 0){
						buffer.append(",");
					}
					field.setAccessible(true);
					Object obj = field.get(bean);
					if(obj == null){
						buffer.append(field.getName()).append("=null");
					}else if(obj instanceof List){
						try{
							List<?> list = (List<?>) obj;
							buffer.append(field.getName()).append("=[size:").append(list.size()).append("]");
						}catch(Exception e){
							buffer.append(field.getName()).append("=").append(obj);
						}
					}else if(obj instanceof Map){
						try{
							Map<?, ?> map = (Map<?, ?>) obj;
							buffer.append(field.getName()).append("=[size:").append(map.size()).append("]");
						}catch(Exception e){
							buffer.append(field.getName()).append("=").append(obj);
						}
					}else if(obj.getClass().isArray()){
						try{
							Object[] objs = (Object[]) obj;
							buffer.append(field.getName()).append("=[size:").append(objs.length).append("]");
						}catch(Exception e){
							buffer.append(field.getName()).append("=").append(obj);
						}
					}else{
						buffer.append(field.getName()).append("=").append(obj);
					}
				}
				clazz = clazz.getSuperclass();
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			buffer.append("|").append(bean.getClass().getSimpleName());
		}
		return buffer.toString();
	}
	
	public static String toString(Throwable e){
		StringWriter sw = new StringWriter();
		try{
			PrintWriter pw = new PrintWriter(sw);
			e.printStackTrace(pw);
			pw.close();
			sw.close();
		}catch(Exception ex){}
		return sw.toString();
	}

	public static String getSysPath()throws Exception{
		String path = StringUtil.class.getProtectionDomain().getCodeSource().getLocation().getFile();
		if(path.endsWith(".jar")){
			return URLDecoder.decode(path.substring(0, path.lastIndexOf("/")), "UTF-8");
		}else{
			return URLDecoder.decode(path.substring(0, path.lastIndexOf("/bin")), "UTF-8");
		}
	}

	public static String getSysGamePath()throws Exception{
		String path = StringUtil.class.getProtectionDomain().getCodeSource().getLocation().getFile();
		if(path.endsWith(".jar")){
			return URLDecoder.decode(path.substring(0, path.indexOf("app/gameserver")), "UTF-8");
		}else{
			path = path.substring(0, path.lastIndexOf("/bin"));
			return URLDecoder.decode(path.substring(0, path.lastIndexOf("/") + 1), "UTF-8");
		}
	}
	
	public static Map<String, Object> parseJSON2Map(String jsonStr) {
		Map<String, Object> map = new HashMap<String, Object>();
		JSONObject json = JSONObject.parseObject(jsonStr);
		for (Object k : json.keySet()) {
			Object v = json.get(k);
			if (v instanceof JSONArray) {
				List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
				Iterator<Object> it = ((JSONArray) v).iterator();
				while (it.hasNext()) {
					JSONObject json2 = (JSONObject) it.next();
					list.add(parseJSON2Map(json2.toString()));
				}
				map.put(k.toString(), list);
			} else {
				map.put(k.toString(), v);
			}
		}
		return map;
	}

    public static String map2jsonstr(Map<Integer,?> map){
        return JSONObject.toJSONString(map);
    }
    public static Map<String,?> jsonstr2map(String jsonstr){
        return JSONObject.parseObject(jsonstr);
    }
	
	public static String enUrlCode(String content, String charset){
		try{
			return URLEncoder.encode(content, charset);
		}catch(Throwable e){
			return content;
		}
	}
	/** 默认编码*/
	public static final String DEFAULT_CHARSET = "UTF-8";
	
	public static String enUrlCode(String content){
		try{
			return URLEncoder.encode(content, DEFAULT_CHARSET);
		}catch(Throwable e){
			return content;
		}
	}

	public static <T> List<List<T>> groupListByGroup(List<T> list, int group) {
		List<List<T>> wrapList = new ArrayList<>();
		if (list == null || list.size() == 0) {
			return wrapList;
		}
		if(group == 1){
			wrapList.add(list.subList(0, list.size()));
			return wrapList;
		}
		int count = 0;
		while (count < list.size()) {
			wrapList.add(list.subList(count, (count + group) > list.size() ? list.size() : (count + group)));
			count += group;
		}
		return wrapList;
	}

	public static String toServerName(int serverId){
		if(serverId <= 0){
			return "S0";
		}
		return new StringBuilder().append("S").append(serverId % 1000).toString();
	}
	
	/**
	 * 字符串转 Unicode 编码
	 * @param string   原字符串
	 * @param halfWith 是否转换半角字符
	 * @return 编码后的字符串
	 */
	public static String strToUnicode(String string, boolean halfWith) {
		if (string == null || string.isEmpty()) {
			return string;
		}
		StringBuilder value = new StringBuilder(string.length() << 3);
		String prefix = "\\u", zerofix = "0", unicode;
		char c;
		for (int i = 0, j; i < string.length(); i++) {
			c = string.charAt(i);
			if (!halfWith && c > 31 && c < 127) {
				// 不转换半角字符
				value.append(c);
				continue;
			}
			value.append(prefix);
			// 高 8 位
			j = c >>> 8;
			unicode = Integer.toHexString(j);
			if (unicode.length() == 1) {
				value.append(zerofix);
			}
			value.append(unicode);
			// 低 8 位
			j = c & 0xFF;
			unicode = Integer.toHexString(j);
			if (unicode.length() == 1) {
				value.append(zerofix);
			}
			value.append(unicode);
		}
		return value.toString();
	}

	/**
	 * Unicode 编码转字符串
	 * @param string 支持 Unicode 编码和普通字符混合的字符串
	 * @return 解码后的字符串
	 */
	public static String unicodeToStr(String string) {
		String prefix = "\\u";
		if (string == null || string.indexOf(prefix) < 0) {
			return string;//传入字符串为空或不包含 Unicode 编码返回原内容
		}
		StringBuilder value = new StringBuilder(string.length() >> 2);
		String[] strings = string.split("\\\\u");
		String hex, mix;
		char hexChar;
		int ascii, n;
		if (strings[0].length() > 0) {
			//处理开头的普通字符串
			value.append(strings[0]);
		}
		try {
			for (int i = 1; i < strings.length; i++) {
				hex = strings[i];
				if (hex.length() > 3) {
					mix = "";
					if (hex.length() > 4) {
						// 处理 Unicode 编码符号后面的普通字符串
						mix = hex.substring(4, hex.length());
					}
					hex = hex.substring(0, 4);
					try {
						Integer.parseInt(hex, 16);
					} catch (Exception e) {
						// 不能将当前 16 进制字符串正常转换为 10 进制数字，拼接原内容后跳出
						value.append(prefix).append(strings[i]);
						continue;
					}
					ascii = 0;
					for (int j = 0; j < hex.length(); j++) {
						hexChar = hex.charAt(j);
						// 将 Unicode 编码中的 16 进制数字逐个转为 10 进制
						n = Integer.parseInt(String.valueOf(hexChar), 16);
						// 转换为 ASCII 码
						ascii += n * ((int) Math.pow(16, (hex.length() - j - 1)));
					}
					// 拼接解码内容
					value.append((char) ascii).append(mix);
				} else {
					// 不转换特殊长度的 Unicode 编码
					value.append(prefix).append(hex);
				}
			}
		} catch (Exception e) {
			return null;// Unicode 编码格式有误，解码失败
		}
		return value.toString();
	}
	
	/**
	 * 对比值
	 * 小于0时str1 < str2
	 * 大于0时str1 > str2
	 * 0作为特殊值
	 * @param str1
	 * @param str2
	 * @return
	 */
	public static int compare(String str1, String str2) {
		if(str1 == null || str2 == null 
				|| (str1 = str1.trim()).length() == 0 
				|| (str2 = str2.trim()).length() == 0){
			return 0;
		}
//		char v1[] = str1.toCharArray();
//		char v2[] = str2.toCharArray();
//		int len1 = v1.length;
//		int len2 = v2.length;
//		int lim = Math.min(len1, len2);
//		int k = 0;
//		while (k < lim) {
//			char c1 = v1[k];
//			char c2 = v2[k];
//			if(c1 == '.'){
//				if(c2 == '.'){
//					k++;
//					continue;
//				}
//				return -1;
//			}else if(c2 == '.'){
//				return 1;
//			}else if (c1 != c2) {
//				return c1 - c2;
//			}
//			k++;
//		}
		String[] s1 = str1.split("\\.");
		String[] s2 = str2.split("\\.");
		int len1 = s1.length;
		int len2 = s2.length;
		int lim = Math.min(len1, len2);
		int k = 0;
		while (k < lim) {
			byte c1 = Byte.valueOf(s1[k]);
			byte c2 = Byte.valueOf(s2[k]);
			if(c1 != c2){
				return c1 - c2;
			}
			k++;
		}
		return len1 - len2;
	}
	

	public static void main(String[] args) {
        try {
        	
            Map<Integer,Object> map = new HashMap<Integer,Object>();
            Map<Integer, Object> tmap = new HashMap<>();
            tmap.put(101, 101);
            tmap.put(102, 102);
            tmap.put(103, 103);
            map.put(1, (Object)tmap);
            tmap = new HashMap<>();
            tmap.put(101, 101);
            tmap.put(102, 102);
            tmap.put(103, 103);
            map.put(2, (Object)tmap);
            String jsonstr = map2jsonstr(map);
            System.out.println("json字符串：" + jsonstr);
            System.out.println("map对象"+parseJSON2Map(jsonstr));
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
	}
}
